﻿using PacoToolKit.Format;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Protocol.SouthGridProtocol
{
    public class PotocolFunctions
    {

        /// <summary>
        /// 计算月冻结时间点个数
        /// </summary>
        /// <param name="beginMonth"></param>
        /// <param name="beginDay"></param>
        /// <param name="endMonth"></param>
        /// <param name="endDay"></param>
        /// <returns></returns>
        public static int CalcMonthRecordCount(int beginMonth, int beginDay, int endMonth, int endDay)
        {
            if (endMonth - beginMonth == 0)
            {
                if (beginMonth == 1) { return 1; }
                else
                {
                    return 0;
                }
            }
            else
            {
                int monthSpan = endMonth - beginMonth;
                if (beginDay == 1) { monthSpan += 1; }
                if (endDay == 1) { monthSpan += 1; }
                return monthSpan;
            }
        }


        /// <summary>
        /// 计算日冻结时间点个数
        /// </summary>
        /// <param name="beginDate"></param>
        /// <param name="endDate"></param>
        /// <returns></returns>
        public static int CalcDayRecordCount(DateTime beginDate, DateTime endDate)
        {
            int daySpan = (endDate - beginDate).Days;
            return daySpan;
        }

        /// <summary>
        /// 计算小时冻结时间点个数
        /// </summary>
        /// <param name="beginDate"></param>
        /// <param name="endDate"></param>
        /// <returns></returns>
        public static int CalcHourRecordCount(DateTime beginDate, DateTime endDate)
        {
            int daySpan = (endDate - beginDate).Days;
            int hourSpan = (endDate.Hour - beginDate.Hour) + 24 * daySpan;
            return hourSpan;
        }

        public static int Calc30MinuteRecordCount(DateTime beginDate, DateTime endDate)
        {
            //int minuteSpan = (endDate - beginDate).Minutes;//相差分钟数
            TimeSpan ts = (endDate - beginDate);
            int minuteSpan = (int)ts.TotalMinutes;
            int count = minuteSpan / 30;
            if ((beginDate.Minute <= 30 && endDate.Minute > 30) || (beginDate.Minute > 30 && endDate.Minute < 30))
            {
                count += 1;//前闭后开
            }
            return count;
        }

        /// <summary>
        /// 格式化读取的内容
        /// </summary>
        /// <param name="diValue">di值</param>
        /// <param name="dataValue">对应di数据值</param>
        /// <returns></returns>
        public static string FormatValue(string diValue, string dataValue)
        {
            string ret = string.Empty;
            string flag = diValue.Substring(0, 4);
            //注意按照长度解析不同类型和长度的数据！！
            if (dataValue.Length.Equals(4))
            {
                //电压
                if (flag.Equals("0201"))
                {
                    if (CheckNegativeNumber(dataValue))
                    {
                        dataValue = GetNegativeNumber(dataValue);
                        ret = "-" + dataValue.Insert(3, ".");
                    }
                    else
                    {
                        ret = dataValue.Insert(3, ".");
                    }
                }
                //功率因数
                else if (flag.Equals("0206"))
                {
                    if (CheckNegativeNumber(dataValue))
                    {
                        dataValue = GetNegativeNumber(dataValue);
                        ret = "-" + dataValue.Insert(1, ".");
                    }
                    else
                    {
                        ret = dataValue.Insert(1, ".");
                    }

                }
            }
            else if (dataValue.Length.Equals(6))
            {
                //三相电流
                if (flag.Equals("0202"))
                {
                    if (CheckNegativeNumber(dataValue))
                    {
                        dataValue = GetNegativeNumber(dataValue);
                        ret = "-" + dataValue.Insert(3, ".");
                    }
                    else
                    {
                        ret = dataValue.Insert(3, ".");
                    }

                }
                //功率
                else if (flag.Equals("0203") || flag.Equals("0204"))
                {
                    if (CheckNegativeNumber(dataValue))
                    {
                        dataValue = GetNegativeNumber(dataValue);
                        ret = "-" + dataValue.Insert(2, ".");
                    }
                    else
                    {
                        ret = dataValue.Insert(2, ".");
                    }

                }
            }
            else if (dataValue.Length.Equals(8))
            {
                ret = dataValue.Insert(6, ".");
            }
            else if (dataValue.Length.Equals(16))
            {
                if (flag == "0101")//需量
                {
                    var value = dataValue.Substring(10, 6);
                    if (CheckNegativeNumber(value))
                    {
                        value = GetNegativeNumber(value);
                        value = "-" + value.Insert(2, ".");
                    }
                    else
                    {
                        value = value.Insert(2, ".");
                    }
                    var date = dataValue.Substring(0, 10);
                    if (!dataValue.Contains("F"))
                    {
                        date = new DateTime(int.Parse("20" + date.Substring(0, 2)), int.Parse(date.Substring(2, 2)), int.Parse(date.Substring(4, 2)), int.Parse(date.Substring(6, 2)), int.Parse(date.Substring(8, 2)), 0).ToString("yyyy-MM-dd hh:mm");
                    }
                    ret = value + "/" + date;
                }
            }
            return ret;
        }


        /// <summary>
        /// 判断是否为负数[非法字符FF也认为是正数]
        /// </summary>
        /// <param name="dataValue"></param>
        /// <returns></returns>
        public static bool CheckNegativeNumber(string dataValue)
        {
            if (IsNumber(dataValue))
            {
                if (int.Parse(dataValue.Substring(0, 1)) >= 8) { return true; }
                else { return false; }
            }
            else
            {
                return false;
            }
        }

        /// <summary>
        /// 判断字符串是否为数字
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static bool IsNumber(string str)
        {
            try
            {
                int.Parse(str);
                return true;
            }
            catch
            {
                return false;
            }

        }

        /// <summary>
        ///正确的负数形式返回
        /// </summary>
        /// <param name="dataValue"></param>
        /// <returns></returns>
        public static string GetNegativeNumber(string dataValue)
        {
            if (int.Parse(dataValue.Substring(0, 1)) >= 8)
            {
                int length = dataValue.Length;
                var binValue = Formater.DECtoBIN(Formater.HEXtoDEC(dataValue));
                //最高位为1，为负数
                binValue = "0" + binValue.Remove(0, 1);
                dataValue = Formater.DECtoHEX(Formater.BINtoDEC(binValue));
                dataValue = Formater.AdjustLengthHead(dataValue, length);
            }
            return dataValue;
        }

        /// <summary>
        /// 计算乘以倍率的各个数据项的值
        /// </summary>
        /// <param name="diValue"></param>
        /// <param name="value"></param>
        /// <param name="ct"></param>
        /// <param name="pt"></param>
        /// <returns></returns>
        public static string CalcRateValue(string diValue, string value, int ct, int pt)
        {

            if (value.Contains("F"))
            {
                return value;
            }
            else
            {
                string flag = diValue.Substring(0, 4);
                //电量
                if (flag.Equals("0001") || flag.Equals("0002") || flag.Equals("0003") || flag.Equals("0004"))
                {
                    return (double.Parse(value) * ct * pt).ToString();
                }
                //功率
                else if (flag.Equals("0203") || flag.Equals("0204"))
                {
                    return (double.Parse(value) * ct * pt).ToString();
                }
                //电流
                else if (flag.Equals("0202"))
                {
                    //return (float.Parse(value) * ct).ToString();
                    return (double.Parse(value) * ct).ToString();
                }
                //电压
                else if (flag.Equals("0201"))
                {
                    return (double.Parse(value) * pt).ToString();
                }
                //需量
                else if (flag.Equals("0101"))
                {
                    var values = value.Split('/');
                    string xuliangValue = (double.Parse(values[0]) * ct * pt).ToString();
                    string xuliangDate = values[1];
                    return xuliangValue + "/" + xuliangDate;
                }
                //其他，比如功率因数
                else
                {
                    return value;
                }
            }
        }

        /// <summary>
        /// 计算除以倍率的各个数据项的值
        /// </summary>
        /// <param name="diValue"></param>
        /// <param name="rateValue"></param>
        /// <param name="ct"></param>
        /// <param name="pt"></param>
        /// <returns></returns>
        public static string CalcValue(string diValue, string rateValue, int ct, int pt)
        {
            if (rateValue.Contains("F"))
            {
                return rateValue;
            }
            else
            {
                string flag = diValue.Substring(0, 4);
                //电量
                if (flag.Equals("0001") || flag.Equals("0002") || flag.Equals("0003") || flag.Equals("0004"))
                {
                    return (double.Parse(rateValue) / ct / pt).ToString("f2");//保留2位小数，四舍五入
                }
                //功率
                else if (flag.Equals("0203") || flag.Equals("0204"))
                {
                    return (double.Parse(rateValue) / ct / pt).ToString("f4");//保留4位小数，四舍五入
                }
                //电流
                else if (flag.Equals("0202"))
                {
                    //return (float.Parse(value) * ct).ToString();
                    return (double.Parse(rateValue) / ct).ToString("f3");//保留3位小数，四舍五入
                }
                //电压
                else if (flag.Equals("0201"))
                {
                    return (double.Parse(rateValue) / pt).ToString("f1");//保留1位小数，四舍五入
                }
                //其他，比如功率因数
                else
                {
                    return rateValue;
                }
            }
        }
    }
}
